<script>

  function ajax({
    method = 'GET',
    url,
    params = {}
  }) {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.open(method, url, true);
      xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status >= 200 && xhr.status < 300) {
          return resolve(JSON.parse(xhr.responseText));
        }
        return reject(new Error(`request error ${request.status}`));
      }
      xhr.send(null);
    })
  }

  // xhr取消请求
  {
    function ajax(url) {
      const xhr = new XMLHttpRequest();
      const promise = new Promise((resolve, reject) => {
        xhr.open('GET', url, true);
        xhr.send();
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300) {
            return resolve(JSON.parse(xhr.responseText));
          }
        }
      })
      return {
        promise,
        xhr
      }
    }
    const {
      promise,
      xhr
    } = ajax('https://httpbin.org/delay/3');
    promise.then(res => {
      console.log(res);
    })
    setTimeout(() => {
      xhr.abort();
    }, 1000)
  }

  // fetch取消请求
  {
    const controller = new AbortController();
    const signal = controller.signal;

    // Register a listenr.
    signal.addEventListener('abort', () => {
      console.log('aborted!');
    });

    function beginFetching() {
      console.log('Now fetching');
      var urlToFetch = 'https://httpbin.org/delay/3';

      fetch(urlToFetch, {
        method: 'get',
        signal: signal,
      })
        .then(function (response) {
          console.log(`Fetch complete. (Not aborted)`);
        })
        .catch(function (err) {
          console.error(` Err: ${err}`);
        });
    }

    function abortFetching() {
      console.log('Now aborting');
      // Abort.
      controller.abort();
    }
  }

</script>